package domain.lexicalAnalyzerGenerator;

import java.util.Iterator;
import java.util.List;

import domain.regularExpression.NonUnaryRegularExpressionOperator;

public class SwitchInstruction extends Instruction {

	List<String> directiveSymbols;
	List<Instruction> subInstructions;

	public SwitchInstruction(NonUnaryRegularExpressionOperator nonUnaryRegularExpressionOperator) 
	throws InstructionException{
		directiveSymbols = Instruction.getDirectiveSymbols(nonUnaryRegularExpressionOperator);
		subInstructions = Instruction.getSubInstructions(nonUnaryRegularExpressionOperator);
	}

	public String generateCode() throws CodeGenerationException {
		String code = "";
		if (subInstructions.size() >= 1){
			code += generateCode(directiveSymbols, subInstructions);

			code += "else {\n";
			code += "	System.out.println(\"El simbolo actual no se corresponde con ningun simbolo esperado.\\n\");\n"; 
			code += "	System.out.println(\"\\n\");\n";
			code += drawExpectedSymbolsInfo(directiveSymbols);
			code += "	System.out.println(\"\\n\");\n";
			code += "	System.out.println(grammarStringHelper.getCurrentTokenInfo());\n";
			code += "	throw new ParseFailedException();\n";
			code += "}\n";
		} else {
			throw new CodeGenerationException("Error en sintaxis: Un switch que no tiene sub instrucciones.");
		}

		return code; 		
	}

	private String generateCode(List<String> directiveSymbols, List<Instruction> subInstructions) 
	throws CodeGenerationException {
		String code = " if (grammarStringHelper.belongsCurrentToken(\"" 
			+ directiveSymbols.get(0) + "\")) {\n"
			+ subInstructions.get(0).generateCode() + "}\n";

		if (subInstructions.size() > 1){
			code += "else" + generateCode(directiveSymbols.subList(1, directiveSymbols.size()),
					subInstructions.subList(1, subInstructions.size()));
		}

		return code;
	}

	private String drawExpectedSymbolsInfo(List<String> directiveSymbols) {
		String info = "";

		info += "	System.out.println(\"**********************\");\n";
		info += "	System.out.println(\"* Simbolos esperados *\");\n";
		info += "	System.out.println(\"**********************\");\n";
		info += "	System.out.println(\"*                    *\");\n";

		Iterator<String> iterator = directiveSymbols.iterator();
		String temporalSymbols = "";
		while(iterator.hasNext()){
			String directiveSymbol = iterator.next(); 
			for (int i = 0; i < directiveSymbol.length(); i++){
				temporalSymbols += directiveSymbol.charAt(i);
				
				if (temporalSymbols.length() == 5){
					drawExpectedSymbolsInfoRow(temporalSymbols);
					temporalSymbols = "";
				}
			}
		}
		if (temporalSymbols.length() > 0){
			info += drawExpectedSymbolsInfoRow(temporalSymbols);
		}
		
		info += "	System.out.println(\"*                    *\");\n";
		info += "	System.out.println(\"**********************\");\n";

		return info;
	}

	private String drawExpectedSymbolsInfoRow(String directiveSymbols) {
		String info = "";
		info += "	System.out.println(\"* ";

		int i = 0;
		while (i < directiveSymbols.length()){
			info += directiveSymbols.charAt(i) + " - ";
			i++;
		}
		// elimino los 2 ultimos caracteres, que quedaron
		// demas para no poner complejidad al while.
		info = info.substring(0, info.length() - 2);

		while (i < 5){
			info += "    ";
			i++;
		}
		
		info += " *\");\n";
		return info;
	}
}
